/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.huahinframework.emanager.rest.service; import java.util.HashMap; import java.util.Map; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.wink.client.Resource; import org.apache.wink.client.RestClient; import org.huahinframework.emanager.amazonaws.elasticmapreduce.Config; import org.huahinframework.emanager.amazonaws.elasticmapreduce.EMRProperties; import org.huahinframework.emanager.queue.QueueUtils; import org.huahinframework.emanager.rest.response.Response; import org.huahinframework.emanager.util.JobUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduce; import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceClient; /** * */ @Path("/jobflow") public class JobFlowService { private static final Log log = LogFactory.getLog(JobFlowService.class); private static final String JOB_FLOW = "JOB_FLOW"; private static final String STEP_NAME = "STEP_NAME"; private static final String RUNNING_PATH = "http://%s:9010/job/list/running"; private static final String KILL_PATH = "http://%s:9010/job/kill/id/%s"; private static final String STATUS_KILLED = "Killed job %s"; private AmazonElasticMapReduce emr; private EMRProperties emrProperties; @Path("/list") @GET @Produces(MediaType.APPLICATION_JSON) public JSONArray list() throws JSONException { return JobUtils.listJobFlow(emr); } @Path("/runnings") @GET @Produces(MediaType.APPLICATION_JSON) public JSONArray runnings() throws JSONException { return JobUtils.runningsJobFlow(emr); } @Path("/describe/{" + JOB_FLOW + "}") @GET @Produces(MediaType.APPLICATION_JSON) public JSONObject describe(@PathParam(JOB_FLOW) String jobFlow) throws JSONException { return JobUtils.getJobFlow(jobFlow, emr); } @Path("/kill/step/{" + STEP_NAME + "}") @DELETE @Produces(MediaType.APPLICATION_JSON) public JSONObject kill(@PathParam(STEP_NAME) String stepName) throws JSONException { Map<String, String> status = new HashMap<String, String>(); status.put(Response.STATUS, stepName + " killed"); try { Config config = QueueUtils.get(stepName); String masterPublicDnsName = config.getMasterPublicDnsName(); if (config.getStatus() != Config.JOB_STATUS_RUNNING || isEmpty(masterPublicDnsName)) { status.put(Response.STATUS, stepName + " not running"); return new JSONObject(status); } Resource resource = null; RestClient client = new RestClient(); resource = client.resource(String.format(RUNNING_PATH, masterPublicDnsName)); JSONArray runnings = resource.get(JSONArray.class); if (runnings.length() != 1) { status.put(Response.STATUS, stepName + " not running"); return new JSONObject(status); } String jobId = runnings.getJSONObject(0).getString("jobid"); resource = client.resource(String.format(KILL_PATH, masterPublicDnsName, jobId)); JSONObject killStatuses = resource.delete(JSONObject.class); String killStatus = killStatuses.getString("status"); if (isEmpty(killStatus) || !killStatus.equals(String.format(STATUS_KILLED, jobId))) { status.put(Response.STATUS, "kill failed"); return new JSONObject(status); } config.setStatus(Config.JOB_STATUS_KILLED); QueueUtils.updateQueue(config); } catch (Exception e) { log.error(e); status.put(Response.STATUS, e.getMessage()); } return new JSONObject(status); } /** * */ public void init() { emr = new AmazonElasticMapReduceClient( new BasicAWSCredentials(emrProperties.getAccessKey(), emrProperties.getSecretKey())); if (!isEmpty(emrProperties.getEndpoint())) { emr.setEndpoint(emrProperties.getEndpoint()); } } /** * */ private boolean isEmpty(String s) { return s == null || s.isEmpty(); } /** * @param emrProperties the emrProperties to set */ public void setEmrProperties(EMRProperties emrProperties) { this.emrProperties = emrProperties; } }